package com.baofu.paycore.manager.storer.impl;

import com.baofu.paycore.common.enums.UpdateUser;
import com.baofu.paycore.common.exception.PayCoreBizException;
import com.baofu.paycore.manager.model.withdraw.WithdrawFundBO;
import com.baofu.paycore.manager.storage.impl.ClearAccountManager;
import com.baofu.paycore.service.facade.enums.PayCoreErrorCode;
import com.baofu.paycore.dal.mapper.ClearAccountMapper;
import com.baofu.paycore.dal.mapper.ClearBankMapper;
import com.baofu.paycore.dal.mapper.ClearMapper;
import com.baofu.paycore.dal.model.base.BaseDO;
import com.baofu.paycore.manager.converter.BO2DOConverter;
import com.baofu.paycore.manager.converter.DO2BOConverter;
import com.baofu.paycore.manager.model.RechargeBO;
import com.baofu.paycore.manager.model.RechargeFundBO;
import com.baofu.paycore.manager.storer.AbstractOrderRepository;
import com.baofu.paycore.service.facade.enums.PayStatusEnums;
import com.google.common.collect.Lists;
import com.baofu.paycore.dal.model.ClearAccountDO;
import com.baofu.paycore.dal.model.ClearBankDO;
import com.baofu.paycore.dal.model.ClearDO;
import com.baofu.paycore.manager.storer.RechargeOrderRepository;
import com.system.commons.sequence.redis.SequenceFacade;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * 充值订单
 *
 * <p/>
 *      1、查询主单信息
 * </p>
 * User: LZQ Date: 2016/04/20  Version: 1.0
 */
@Slf4j
@Repository
public class RechargeOrderRepositoryImpl extends AbstractOrderRepository<RechargeBO> implements RechargeOrderRepository {

    /**
     * 充值主单mapper
     */
    @Autowired
    private ClearMapper clearMapper;

    /**
     * 充值资金单mapper
     */
    @Autowired
    private ClearAccountMapper clearAccountMapper;

    /**
     * 充值银行单mapper
     */
    @Autowired
    private ClearBankMapper clearBankMapper;

    /**
     * sequence生成类
     */
    @Autowired
    private SequenceFacade sequenceFacade;

    /**
     *资金单处理manager
     */
    @Autowired
    private ClearAccountManager clearAccountManager;

    /**
     * 订单转换
     *
     * @param rechargeBO 支付对象
     * @return 转换后DO
     */
    @Override
    protected List<BaseDO> convertToDO(RechargeBO rechargeBO) {

        List<BaseDO> list = Lists.newArrayList();
        //充值主单
        ClearDO clearDO = BO2DOConverter.getClearDO(rechargeBO);
        list.add(clearDO);

        //充值银行单
        if(null != rechargeBO.getRechargeBankBO()) {
            ClearBankDO clearBankDO = BO2DOConverter.getClearBankDO(rechargeBO.getRechargeBankBO());
            clearBankDO.setCreatedBy(rechargeBO.getOperator());
            clearBankDO.setUpdatedBy(rechargeBO.getOperator());
            list.add(clearBankDO);
        }

        //充值资金单
        for (RechargeFundBO rechargeFundBO : rechargeBO.getRechargeFundBO()){
            ClearAccountDO clearAccountDO = BO2DOConverter.getClearAccountDO(rechargeFundBO);
            clearAccountDO.setUpdatedBy(rechargeBO.getOperator());
            clearAccountDO.setCreatedBy(rechargeBO.getOperator());
            list.add(clearAccountDO);
        }

        return list;
    }

    /**
     * 加载并锁定订单
     *
     * @param requestOrderNo   请求订单号
     * @param requestBizNo     请求流水号
     * @return                 支付信息
     */
    @Override
    public RechargeBO lock(String requestOrderNo, String requestBizNo,String requestSystem) {
        return null;
    }

    /**
     * 加载订单
     *
     * @param requestOrderNo    支付单号
     * @return                  订单
     */
    @Override
    public RechargeBO load(String requestOrderNo) {

        //充值资金单
        ClearBankDO clearBankDO = clearBankMapper.queryClearBankByPayNo(requestOrderNo);
        if (clearBankDO == null) {
            log.error("查询充值资金单信息为空 fundDetailNo:{}", requestOrderNo);
            throw new PayCoreBizException(PayCoreErrorCode.ORDER_IS_NOT_EXISTED);
        }
        /*if (PayStatusEnums.SUCCESS.getCode().equals(clearBankDO.getStatus())) {
            log.error("查询充值资金单信息状态为成功 fundDetailNo:{}", requestOrderNo);
            throw new PayCoreBizException(PayCoreErrorCode.RECHARGE_ORDER_IS_SUCCESS);
        }*/
        //主单
        ClearDO clearDO = clearMapper.queryClearByPayNo(clearBankDO.getPayNo());
        //充值资金单
        List<ClearAccountDO> clearAccountDO = clearAccountMapper.queryClearAccountByPayNo(clearBankDO.getPayNo());

        return DO2BOConverter.buildRechargeBO(clearDO, clearAccountDO, clearBankDO);
    }

    /**
     * 依支付单号加载订单数据
     *
     * @param payNo     支付单号
     * @return          RechargeBO
     */
    public RechargeBO loadOrderByPayNo(String payNo){
        //主单
        ClearDO clearDO = clearMapper.queryClearByPayNo(payNo);
        if (null == clearDO){
            log.error("充值主单信息为空 payNo:{}", payNo);
            throw new PayCoreBizException(PayCoreErrorCode.ORDER_IS_NOT_EXISTED);
        }
        //充值资金单
        ClearBankDO clearBankDO = clearBankMapper.queryClearBankInfo(payNo);

        //充值资金单
        List<ClearAccountDO> clearAccountDO = clearAccountMapper.queryClearAccountByPayNo(payNo);

        return DO2BOConverter.buildRechargeBO(clearDO, clearAccountDO, clearBankDO);
    }


    @Transactional(isolation = Isolation.DEFAULT,
            propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void addRetryOrder(RechargeFundBO rechargeFundBO,String operator) {
        ClearAccountDO clearAccountDO = BO2DOConverter.getClearAccountDO(rechargeFundBO);
        clearAccountDO.setDescription("discard");
        clearAccountMapper.updateDiscard(clearAccountDO);
        clearAccountDO.setFundDetailNo(sequenceFacade.getUniqueSeq());
        clearAccountDO.setStatus(PayStatusEnums.INIT.getCode());
        clearAccountDO.setDescription(null);
        clearAccountDO.setErrorCode(null);
        clearAccountDO.setErrorReason(null);
        rechargeFundBO.setFundDetailNo(clearAccountDO.getFundDetailNo());
        clearAccountDO.setCreatedBy(operator);
        clearAccountDO.setUpdatedBy(StringUtils.isEmpty(operator) ? UpdateUser.SYS.getUserName() : operator);
        clearAccountManager.addOrder(clearAccountDO);
    }

    @Override
    public void updateRetry(RechargeBO rechargeBO) {
        ClearDO clearDO = BO2DOConverter.getClearDO(rechargeBO);
        clearMapper.updateRetry(clearDO);
        //充值资金单
        for (RechargeFundBO rechargeFundBO : rechargeBO.getRechargeFundBO()){
            ClearAccountDO clearAccountDO = BO2DOConverter.getClearAccountDO(rechargeFundBO);
            clearAccountDO.setUpdatedBy(rechargeBO.getOperator());
            clearAccountDO.setCreatedBy(rechargeBO.getOperator());
            clearAccountMapper.updateDiscard(clearAccountDO);
        }
    }

    /**
     * 幂等性校验
     *
     * @param requestBizNo     请求流水号
     * @param requestOrderNo   请求订单号
     * @return                 订单
     */
    @Override
    public RechargeBO checkIdempotent(String requestBizNo, String requestOrderNo,String requestSystem) {
        ClearDO clearDO = clearMapper.queryByOrderNo(requestOrderNo,requestBizNo,null,requestSystem);
        return DO2BOConverter.getRechargeBOByDO(clearDO);
    }

}
